package com.abc.config;

import com.abc.shiro.ShiroFormAuthenticationFilter;
import com.abc.shiro.UserRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;

@Configuration
public class ShiroConfig {

    @Bean
    public Realm realm() {
        return new UserRealm();
    }

    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        /**
         * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。
         * 在@Controller注解的类的方法中加入@RequiresRole注解，会导致该方法无法映射请求，导致返回404。
         * 加入这项配置能解决这个bug
         */
        creator.setUsePrefix(true);
        return creator;
    }

    /**
     * 这里统一做鉴权，即判断哪些请求路径需要用户登录，哪些请求路径不需要用户登录。
     * 这里只做鉴权，不做权限控制，因为权限用注解来做。
     *
     * @return
     */
//    @Bean
//    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
//        DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition();
//        //哪些请求可以匿名访问
//        chain.addPathDefinition("/auth/login", "anon");
//        chain.addPathDefinition("/auth/logout", "anon");
//        chain.addPathDefinition("/page/401", "anon");
//        chain.addPathDefinition("/page/403", "anon");
//        chain.addPathDefinition("/page/index", "anon");
//        chain.addPathDefinition("/web", "anon");
//        chain.addPathDefinition("/web/*", "anon");
//        chain.addPathDefinition("/web/**", "anon");
//
//        //除了以上的请求外，其它请求都需要登录
//        chain.addPathDefinition("/**", "authc");
//        LinkedHashMap<String, Filter> filtsMap = new LinkedHashMap<String, Filter>();
//        filtsMap.put("authc", new ShiroFormAuthenticationFilter());
//        chain.
//        return chain;
//    }


    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setLoginUrl("/");
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //配置访问权限
        LinkedHashMap<String, String> chain = new LinkedHashMap<String, String>();
        chain.put("/web/**", "anon");
        chain.put("/static/**", "anon");
        chain.put("/api/v1/auth/login", "anon");
        chain.put("/api/v1/auth/logout", "anon");
        chain.put("/page/401", "anon");
        chain.put("/page/403", "anon");
        chain.put("/page/index", "anon");
        chain.put("/css/**", "anon");
        chain.put("/js/**", "anon");
        chain.put("/assets/**", "anon");
        chain.put("/upload/**", "anon");


        chain.put("/api/v1/**", "authc");
        chain.put("/**", "anon");
        LinkedHashMap<String, Filter> filtsMap = new LinkedHashMap<String, Filter>();
        filtsMap.put("authc", new ShiroFormAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filtsMap);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(chain);
        return shiroFilterFactoryBean;
    }


}
